import { devParam } from '../sqlQuery'

import { deepMerge, typeOf, domainid, formatDate, deepCopy, getNowDate } from '../utils'
import { format } from 'date-fns'

const socket_ems = (param, sessionId) => {
  const createsql = {
    param: {
      domain_id: domainid(),
      date: param.param.date || [
        param.param.startDateTime || `${format(getNowDate(), 'yyyy-MM-dd')} 00:00:00`,
        `${format(getNowDate(), 'yyyy-MM-dd')} 23:59:59`
      ]
    },
    session_id: sessionId
  }
  // let env = process.env.NODE_ENV
  // if (env == 'development') {
  //   //开发环境,返回sql
  //   let dataset = Jons[param.application][param.datasource][param.name]
  //   let params = Object.assign({}, devParam(deepMerge(createsql, param)), {
  //     query: dataset
  //   })
  //   return params
  // } else {
  return devParam(deepMerge(createsql, param))
  // }
}

class SocketPlugin {
  constructor() {
    this.websocket = null
    this.isConnect = false //是否链接成功
    this.timeoutNum = null
    this.isActivelyClose = false //是否手动断开，true是手动关闭
    this.callback = {} //已发回调
    this.notcallback = {} //未发回调
    this.param = {} //已发数据
    this.notparam = {} //未发数据
    this.lastTime = {}
    this.timer = 0
  }
  connect() {
    //初始化
    try {
      if (!this.websocket) {
        this.websocket = new WebSocket(import.meta.env.VITE_CLOUD_SOCKET_BASE_URL + new Date().getTime())
      }
      return this.initSocket()
    } catch (error) {
      this.reconnectSocket()
    }
  }
  initSocket() {
    return new Promise((resolve, reject) => {
      this.isActivelyClose = false
      this.websocket.onclose = e => {
        console.log('websocket连接关闭~')
        this.websocket = null
        this.isConnect = false
        // 如果手动关闭则不进行重连
        if (!this.isActivelyClose) {
          this.notparam = deepCopy(this.param)
          this.reconnectSocket()
        }
      }
      this.websocket.onerror = e => {
        console.log('websocket发生异常~' + e)
        this.websocket = null
        this.isConnect = false
        this.notparam = deepCopy(this.param)
        this.reconnectSocket()
      }

      this.websocket.onopen = e => {
        console.log('websocket已连接~ ')
        this.timer = 0
        this.isConnect = true
        resolve('已注册完成')
      }
      this.websocket.onmessage = e => {
        let currentSession = JSON.parse(e.data).session_id
        if (!currentSession) return false //判断是否是直接返回了200
        let currentTime = JSON.parse(e.data).msg ? JSON.parse(e.data).msg.time : ''
        if (!currentTime) {
          currentTime = format(getNowDate(), 'yyyy-MM-dd HH:mm:ss')
        } else if (typeOf(currentTime) == 'array') {
          currentTime = currentTime.pop()
        }
        if (Object.keys(this.param).includes(currentSession)) {
          this.send({ session_id: currentSession })
        }
        if (this.callback[currentSession]) {
          //   if (store.getParallelSpace.open) {
          //     this.lastTime[currentSession] = currentTime
          //     this.callback[currentSession](JSON.parse(e.data))
          //   } else
          if (!this.lastTime[currentSession] || formatDate(this.lastTime[currentSession]) <= formatDate(currentTime)) {
            this.lastTime[currentSession] = currentTime
            this.callback[currentSession](JSON.parse(e.data))
          }
        }
      }
    })
  }

  reconnectSocket() {
    //开始重连
    console.log('websocket 重新连接~ ')
    this.timeoutNum && clearTimeout(this.timeoutNum) //??
    this.timeoutNum = setTimeout(() => {
      this.connect().then(res => {
        console.log('监听')
        this.sendSession()
      })
    }, this.timer * 1000)
    this.timer = this.timer === 0 ? 2 : this.timer === 64 ? 64 : this.timer * 2
  }

  sendSession() {
    //判断未发的数据有没有,有则先把未发得数据发送了
    if (Object.keys(this.notparam).length) {
      Object.keys(this.notparam).forEach(item => {
        let param = this.notparam[item]
        // param['Time-Engine'] = store.state.parallelSpace.open ? 1 : 0
        param['Time-Engine'] = 0
        if (param.name && param.datasource) {
          this.websocket.send(JSON.stringify(socket_ems(param, item)))
        } else {
          this.websocket.send(JSON.stringify({ ...param, session_id: item }))
        }
        delete this.notparam[item] //删除未发数据
        this.param[item] = param //添加到已发数据
      })
    }
  }
  // 发送消息,这里只会手动触发
  send(param, sessionId = '', callback) {
    // 先行缓存
    if (sessionId) {
      //初始处理回调
      if (callback) {
        this.callback[sessionId] = callback
      }
      this.notparam[sessionId] = param
    }
    //开始发送数据
    //状态已链接的情况下
    if (this.isConnect) {
      if (sessionId) {
        this.sendSession(param, sessionId)
      }
      // 直接发送
      else {
        this.websocket.send(JSON.stringify(param))
      }
    } else {
      this.reconnectSocket()
    }
  }

  onUnmoun(sessionIdArray) {
    if (!Array.isArray(sessionIdArray)) {
      console.error('销毁示例请传入数组')
      return false
    }
    if (!sessionIdArray.length) return
    console.log('要卸载的', sessionIdArray)
    console.log('目前存在的', deepCopy(this.param))

    let deleteKeys = []
    sessionIdArray.forEach(element => {
      let keys = Object.keys(this.param)
      keys.forEach(item => {
        if (element && item.indexOf(element.slice(0, 5)) >= 0) {
          deleteKeys.push(item)
          Reflect.deleteProperty(this.param, item)
          Reflect.deleteProperty(this.notparam, item)
          Reflect.deleteProperty(this.callback, item)
          Reflect.deleteProperty(this.lastTime, item)
        }
      })
    })
    this.websocket.send(
      JSON.stringify({
        unregister: true,
        session_id: deleteKeys.join(',')
      })
    )
    console.log('删除完成的', this.param)
  }
  close() {
    //close关闭连接
    try {
      this.isActivelyClose = true
      if (this.websocket) {
        this.websocket.close()
      }
    } catch (error) {}
  }
}

export default SocketPlugin

// 使用方法备注
// let  socketConfig = {
//     url: '/ints/websocket/test',
//     callback: this.getSocketMsg,
//     msg: {
//       fanId: '01'
//     }
//  }
// let  testSocket = new SocketPlugin(socketConfig)
// // 初始化
// testSocket.connect()
// // 发送消息
// testSocket.send(socketConfig.msg)
// // 关闭
// testSocket.close()
